<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>康复锻炼计时器</title>
    <style>
        /* 样式保持不变 */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Microsoft YaHei", sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 10px;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        
        .container {
            width: 100%;
            max-width: 400px;
            background: white;
            border-radius: 16px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.15);
            overflow: hidden;
        }
        
        .header {
            background: #2E86AB;
            color: white;
            padding: 20px;
            text-align: center;
        }
        
        .header h1 {
            font-size: 20px;
            font-weight: bold;
            margin-bottom: 4px;
        }
        
        .header p {
            font-size: 12px;
            opacity: 0.9;
            text-align: center;
            letter-spacing: 1px;
        }
        
        .settings {
            padding: 15px;
            background: #F8F9FA;
        }
        
        .setting-group {
            display: flex;
            align-items: center;
            justify-content: space-between;
            margin-bottom: 12px;
            padding: 12px;
            background: white;
            border-radius: 8px;
            box-shadow: 0 1px 6px rgba(0,0,0,0.05);
        }
        
        .setting-group label {
            font-weight: 600;
            color: #333;
            font-size: 14px;
        }
        
        .setting-group input {
            width: 70px;
            padding: 6px 10px;
            border: 2px solid #e9ecef;
            border-radius: 6px;
            text-align: center;
            font-size: 14px;
        }
        
        .progress-section {
            padding: 20px;
            text-align: center;
        }
        
        .count-display {
            font-size: 36px;
            font-weight: bold;
            color: #2E86AB;
            margin-bottom: 15px;
        }
        
        .progress-bar {
            width: 100%;
            height: 16px;
            background: #e9ecef;
            border-radius: 8px;
            overflow: hidden;
            margin-bottom: 12px;
        }
        
        .progress-fill {
            height: 100%;
            background: linear-gradient(90deg, #27AE60, #2E86AB);
            transition: width 0.3s ease;
            width: 0%;
        }
        
        .time-info {
            display: flex;
            justify-content: space-between;
            font-size: 12px;
            color: #666;
            margin-bottom: 12px;
        }
        
        .countdown {
            font-size: 16px;
            font-weight: 600;
            color: #E67E22;
            margin: 8px 0;
            min-height: 24px;
        }
        
        .audio-notice {
            background: #fff3cd;
            border: 1px solid #ffeaa7;
            border-radius: 6px;
            padding: 8px;
            margin: 8px 0;
            font-size: 12px;
            color: #856404;
            text-align: center;
        }
        
        .wake-lock-notice {
            background: #d1ecf1;
            border: 1px solid #bee5eb;
            border-radius: 6px;
            padding: 8px;
            margin: 8px 0;
            font-size: 12px;
            color: #0c5460;
            text-align: center;
        }
        
        .controls {
            padding: 15px;
            display: flex;
            gap: 8px;
        }
        
        .btn {
            flex: 1;
            padding: 12px 8px;
            border: none;
            border-radius: 10px;
            font-size: 14px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s ease;
            min-height: 50px;
        }
        
        .btn:active {
            transform: scale(0.95);
        }
        
        .start-btn {
            background: #27AE60;
            color: white;
        }
        
        .pause-btn {
            background: #E67E22;
            color: white;
        }
        
        .reset-btn {
            background: #95A5A6;
            color: white;
        }
        
        .btn:disabled {
            opacity: 0.6;
            cursor: not-allowed;
            transform: none;
        }

        /* 小屏幕优化 */
        @media (max-width: 380px) {
            body {
                padding: 5px;
            }
            
            .container {
                border-radius: 12px;
            }
            
            .header {
                padding: 15px;
            }
            
            .header h1 {
                font-size: 18px;
            }
            
            .count-display {
                font-size: 32px;
                margin-bottom: 12px;
            }
            
            .progress-section {
                padding: 15px;
            }
            
            .controls {
                padding: 12px;
                gap: 6px;
            }
            
            .btn {
                padding: 10px 6px;
                font-size: 13px;
                min-height: 45px;
            }
        }

        /* 超小屏幕优化 */
        @media (max-height: 700px) {
            .header {
                padding: 15px;
            }
            
            .settings {
                padding: 12px;
            }
            
            .progress-section {
                padding: 15px;
            }
            
            .count-display {
                font-size: 32px;
                margin-bottom: 12px;
            }
            
            .countdown {
                font-size: 14px;
                margin: 6px 0;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>🏃 康复锻炼计时器</h1>
            <p>Designed by Tai Xupeng</p>
        </div>
        
        <div class="settings">
            <div class="setting-group">
                <label>设定次数：</label>
                <div>
                    <input type="number" id="totalCount" value="10" min="1" max="1000">
                    <span>次</span>
                </div>
            </div>
            <div class="setting-group">
                <label>间隔时间：</label>
                <div>
                    <input type="number" id="interval" value="5" min="1" max="300">
                    <span>秒</span>
                </div>
            </div>
        </div>
        
        <div class="progress-section">
            <div class="count-display" id="countDisplay">0/10</div>
            <div class="progress-bar">
                <div class="progress-fill" id="progressFill"></div>
            </div>
            <div class="time-info">
                <span id="totalTime">总时间: 00:00:00</span>
                <span id="nextBeep">下一次提示: --</span>
            </div>
            <div class="countdown" id="countdown">准备时间: --</div>
            
            <!-- Wake Lock 提示 -->
            <div class="wake-lock-notice" id="wakeLockNotice">
                📱 屏幕保持：点击开始后会自动保持屏幕常亮
            </div>
            
            <!-- 音频提示 -->
            <div class="audio-notice" id="audioNotice">
                🔊 提示：请点击下方按钮激活声音提示功能
            </div>
        </div>
        
        <div class="controls">
            <button class="btn start-btn" id="startBtn">▶️ 开始</button>
            <button class="btn pause-btn" id="pauseBtn" disabled>⏸️ 暂停</button>
            <button class="btn reset-btn" id="resetBtn">🔄 重置</button>
        </div>
    </div>

    <script>
// 页面加载后立即设置全局点击激活
document.addEventListener('DOMContentLoaded', function() {
    let audioActivated = false;
    
    // 全局点击激活音频
    function activateAudioGlobal() {
        if (!audioActivated) {
            // 创建并立即销毁一个音频上下文来激活权限
            try {
                const audioContext = new (window.AudioContext || window.webkitAudioContext)();
                const buffer = audioContext.createBuffer(1, 1, 22050);
                const source = audioContext.createBufferSource();
                source.buffer = buffer;
                source.connect(audioContext.destination);
                source.start();
                source.stop(audioContext.currentTime + 0.001);
                
                audioActivated = true;
                console.log('音频权限已全局激活');
                
                // 更新提示信息
                const audioNotice = document.getElementById('audioNotice');
                if (audioNotice) {
                    audioNotice.innerHTML = '🔊🔊 声音提示已激活 - 可使用手机音量键调节';
                    audioNotice.style.background = '#d4edda';
                }
            } catch (e) {
                console.warn('音频激活失败:', e);
            }
        }
    }
    
    // 页面任何地方点击都激活音频
    document.body.addEventListener('click', activateAudioGlobal, { once: true });
    
    // 5秒后如果还没点击，自动尝试激活（针对某些浏览器的特殊要求）
    setTimeout(activateAudioGlobal, 5000);
});


        class RehabTimer {
            constructor() {
                this.isRunning = false;
                this.paused = false;
                this.currentCount = 0;
                this.totalCount = 10;
                this.interval = 5;
                this.startTime = null;
                this.lastBeepTime = null;
                this.countdownFinished = false;
                this.pauseTime = null;
                this.audioEnabled = false;
                this.audioContext = null;
                this.completionSoundPlaying = false;
                this.wakeLock = null; // Wake Lock 实例
                this.wakeLockSupported = false; // 是否支持 Wake Lock
                
                this.remainingCountdown = 10;
                this.countdownInterval = null;
                
                this.initializeElements();
                this.setupEventListeners();
                this.checkWakeLockSupport();
                this.setupVisibilityHandler();
                this.updateDisplay();
            }
            
            initializeElements() {
                this.countDisplay = document.getElementById('countDisplay');
                this.progressFill = document.getElementById('progressFill');
                this.totalTimeEl = document.getElementById('totalTime');
                this.nextBeepEl = document.getElementById('nextBeep');
                this.countdownEl = document.getElementById('countdown');
                this.audioNotice = document.getElementById('audioNotice');
                this.wakeLockNotice = document.getElementById('wakeLockNotice');
                this.startBtn = document.getElementById('startBtn');
                this.pauseBtn = document.getElementById('pauseBtn');
                this.resetBtn = document.getElementById('resetBtn');
                this.totalCountInput = document.getElementById('totalCount');
                this.intervalInput = document.getElementById('interval');
            }
            
            // 检查是否支持 Wake Lock
            async checkWakeLockSupport() {
                if ('wakeLock' in navigator) {
                    try {
                        this.wakeLockSupported = true;
                        this.wakeLockNotice.innerHTML = '📱 屏幕保持：支持屏幕常亮功能';
                        this.wakeLockNotice.style.background = '#d4edda';
                        this.wakeLockNotice.style.borderColor = '#c3e6cb';
                        this.wakeLockNotice.style.color = '#155724';
                    } catch (err) {
                        this.wakeLockSupported = false;
                        this.wakeLockNotice.innerHTML = '📱 屏幕保持：不支持屏幕常亮，请保持屏幕亮起';
                        this.wakeLockNotice.style.background = '#f8d7da';
                        this.wakeLockNotice.style.borderColor = '#f5c6cb';
                        this.wakeLockNotice.style.color = '#721c24';
                    }
                } else {
                    this.wakeLockSupported = false;
                    this.wakeLockNotice.innerHTML = '📱 屏幕保持：浏览器不支持屏幕常亮，请保持屏幕亮起';
                    this.wakeLockNotice.style.background = '#fff3cd';
                    this.wakeLockNotice.style.borderColor = '#ffeaa7';
                    this.wakeLockNotice.style.color = '#856404';
                }
            }
            
            // 请求 Wake Lock
            async requestWakeLock() {
                if (!this.wakeLockSupported) return;
                
                try {
                    this.wakeLock = await navigator.wakeLock.request('screen');
                    console.log('Wake Lock 已激活');
                    
                    this.wakeLock.addEventListener('release', () => {
                        console.log('Wake Lock 已被释放');
                    });
                    
                } catch (err) {
                    console.warn('无法激活 Wake Lock:', err);
                }
            }
            
            // 释放 Wake Lock
            releaseWakeLock() {
                if (this.wakeLock) {
                    this.wakeLock.release();
                    this.wakeLock = null;
                }
            }
            
            setupEventListeners() {
                const activateAudio = () => {
                    if (!this.audioEnabled) {
                        this.initializeAudio();
                    }
                };
                
                this.startBtn.addEventListener('click', () => {
                    activateAudio();
                    this.startTimer();
                });
                this.pauseBtn.addEventListener('click', () => {
                    activateAudio();
                    this.pauseTimer();
                });
                this.resetBtn.addEventListener('click', () => {
                    activateAudio();
                    this.resetTimer();
                });
                
                this.totalCountInput.addEventListener('change', () => {
                    this.totalCount = parseInt(this.totalCountInput.value) || 10;
                    this.updateDisplay();
                });
                
                this.intervalInput.addEventListener('change', () => {
                    this.interval = parseInt(this.intervalInput.value) || 5;
                });
            }
            
            setupVisibilityHandler() {
                // 当页面重新可见时，重新请求 Wake Lock
                document.addEventListener('visibilitychange', async () => {
                    if (document.visibilityState === 'visible' && this.isRunning && !this.paused) {
                        if (this.wakeLockSupported) {
                            await this.requestWakeLock();
                        }
                        // 恢复音频上下文
                        if (this.audioEnabled && this.audioContext) {
                            await this.resumeAudioContext();
                        }
                    }
                });
            }
            
            async resumeAudioContext() {
                if (this.audioContext && this.audioContext.state === 'suspended') {
                    try {
                        await this.audioContext.resume();
                        console.log('音频上下文已恢复');
                    } catch (error) {
                        console.warn('恢复音频上下文失败:', error);
                    }
                }
            }
            
            initializeAudio() {
                try {
                    this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
                    
                    // 播放一个无声的音频来激活音频上下文
                    const buffer = this.audioContext.createBuffer(1, 1, 22050);
                    const source = this.audioContext.createBufferSource();
                    source.buffer = buffer;
                    source.connect(this.audioContext.destination);
                    source.start();
                    
                    this.audioEnabled = true;
                    this.audioNotice.innerHTML = '🔊 声音提示已激活 - 可使用手机音量键调节';
                    this.audioNotice.style.background = '#d4edda';
                    this.audioNotice.style.borderColor = '#c3e6cb';
                    this.audioNotice.style.color = '#155724';
                    
                } catch (e) {
                    this.audioEnabled = false;
                    this.audioNotice.innerHTML = '🔇 设备不支持声音提示';
                    this.audioNotice.style.background = '#f8d7da';
                    this.audioNotice.style.borderColor = '#f5c6cb';
                    this.audioNotice.style.color = '#721c24';
                }
            }
            
            async playBeep() {
                if (!this.audioEnabled || !this.audioContext) {
                    this.vibrate();
                    return;
                }
                
                try {
                    // 确保音频上下文处于运行状态
                    await this.resumeAudioContext();
                    
                    const oscillator = this.audioContext.createOscillator();
                    const gainNode = this.audioContext.createGain();
                    
                    oscillator.connect(gainNode);
                    gainNode.connect(this.audioContext.destination);
                    
                    oscillator.frequency.value = 800;
                    oscillator.type = 'sine';
                    
                    gainNode.gain.setValueAtTime(0.3, this.audioContext.currentTime);
                    gainNode.gain.exponentialRampToValueAtTime(0.01, this.audioContext.currentTime + 0.3);
                    
                    oscillator.start(this.audioContext.currentTime);
                    oscillator.stop(this.audioContext.currentTime + 0.3);
                    
                } catch (e) {
                    console.warn('播放提示音失败，使用振动:', e);
                    this.vibrate();
                }
            }
            
            async playCompletionSound() {
                return new Promise(async (resolve) => {
                    if (!this.audioEnabled || !this.audioContext) {
                        this.vibrate(500);
                        setTimeout(resolve, 800);
                        return;
                    }
                    
                    try {
                        // 确保音频上下文处于运行状态
                        await this.resumeAudioContext();
                        
                        this.completionSoundPlaying = true;
                        
                        const oscillator = this.audioContext.createOscillator();
                        const gainNode = this.audioContext.createGain();
                        
                        oscillator.connect(gainNode);
                        gainNode.connect(this.audioContext.destination);
                        
                        // 播放悦耳的完成音
                        oscillator.frequency.setValueAtTime(523.25, this.audioContext.currentTime);
                        oscillator.frequency.setValueAtTime(659.25, this.audioContext.currentTime + 0.2);
                        oscillator.frequency.setValueAtTime(783.99, this.audioContext.currentTime + 0.4);
                        oscillator.frequency.setValueAtTime(1046.50, this.audioContext.currentTime + 0.6);
                        
                        oscillator.type = 'sine';
                        gainNode.gain.setValueAtTime(0.3, this.audioContext.currentTime);
                        gainNode.gain.exponentialRampToValueAtTime(0.01, this.audioContext.currentTime + 1);
                        
                        oscillator.start(this.audioContext.currentTime);
                        oscillator.stop(this.audioContext.currentTime + 1);
                        
                        // 声音播放完成后resolve
                        oscillator.onended = () => {
                            this.completionSoundPlaying = false;
                            resolve();
                        };
                        
                    } catch (e) {
                        console.warn('播放完成音失败，使用振动:', e);
                        this.vibrate(500);
                        setTimeout(resolve, 800);
                    }
                });
            }
            
            vibrate(duration = 200) {
                if (navigator.vibrate) {
                    navigator.vibrate(duration);
                }
            }
            
            updateDisplay() {
                this.countDisplay.textContent = `${this.currentCount}/${this.totalCount}`;
                this.progressFill.style.width = `${(this.currentCount / this.totalCount) * 100}%`;
                
                if (this.startTime && !this.paused) {
                    const currentTime = this.isRunning ? Date.now() : this.completionTime || Date.now();
                    const elapsed = (currentTime - this.startTime) / 1000;
                    const hours = Math.floor(elapsed / 3600);
                    const minutes = Math.floor((elapsed % 3600) / 60);
                    const seconds = Math.floor(elapsed % 60);
                    this.totalTimeEl.textContent = `总时间: ${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
                }
                
                if (this.isRunning && !this.paused && this.lastBeepTime) {
                    const remaining = this.interval - (Date.now() - this.lastBeepTime) / 1000;
                    if (remaining > 0) {
                        this.nextBeepEl.textContent = `下一次提示: ${remaining.toFixed(1)}秒`;
                    }
                }
            }
            
            async startTimer() {
                if (this.isRunning) return;
                
                this.totalCount = parseInt(this.totalCountInput.value) || 10;
                this.interval = parseInt(this.intervalInput.value) || 5;
                
                if (this.totalCount <= 0 || this.interval <= 0) {
                    alert('请输入有效的数字');
                    return;
                }
                
                if ('Notification' in window && Notification.permission === 'default') {
                    await Notification.requestPermission();
                }
                
                // 请求 Wake Lock 保持屏幕亮起
                await this.requestWakeLock();
                
                this.isRunning = true;
                this.paused = false;
                this.currentCount = 0;
                this.startTime = Date.now();
                this.countdownFinished = false;
                this.completionTime = null;
                this.remainingCountdown = 10;
                
                this.updateDisplay();
                
                this.startBtn.disabled = true;
                this.pauseBtn.disabled = false;
                
                this.countdownEl.textContent = '准备中...';
                this.countdownEl.style.color = '#E67E22';
                
                this.startCountdown();
            }
            
            startCountdown() {
                let countdown = this.remainingCountdown;
                
                // 清除之前的倒计时
                if (this.countdownInterval) {
                    clearInterval(this.countdownInterval);
                }
                
                this.countdownInterval = setInterval(() => {
                    if (!this.isRunning || this.paused) {
                        clearInterval(this.countdownInterval);
                        return;
                    }
                    
                    this.countdownEl.textContent = `准备时间: ${countdown}秒`;
                    this.remainingCountdown = countdown; // 记录剩余时间
                    
                    if (countdown <= 0) {
                        clearInterval(this.countdownInterval);
                        this.countdownEl.textContent = '开始锻炼！';
                        this.countdownEl.style.color = '#27AE60';
                        this.countdownFinished = true;
                        
                        this.playBeep();
                        this.currentCount = 1;
                        this.lastBeepTime = Date.now();
                        this.updateDisplay();
                        this.startMainTimer();
                    }
                    
                    countdown--;
                }, 1000);
            }
            
            startMainTimer() {
                this.timerLoop();
            }
            
            timerLoop() {
                if (!this.isRunning || this.paused) return;
                
                const currentTime = Date.now();
                const elapsed = (currentTime - this.lastBeepTime) / 1000;
                
                if (elapsed >= this.interval) {
                    this.playBeep();
                    this.currentCount++;
                    this.lastBeepTime = currentTime;
                    this.updateDisplay();
                    
                    if (this.currentCount >= this.totalCount) {
                        this.completeTimer();
                        return;
                    }
                }
                
                this.updateDisplay();
                
                if (this.isRunning && !this.paused) {
                    setTimeout(() => this.timerLoop(), 100);
                }
            }
            
            pauseTimer() {
                if (!this.isRunning) return;
                
                this.paused = !this.paused;
                
                if (this.paused) {
                    this.pauseTime = Date.now();
                    this.pauseBtn.textContent = '▶️ 继续';
                    this.countdownEl.textContent = '已暂停';
                    this.countdownEl.style.color = '#95A5A6';
                    this.nextBeepEl.textContent = '下一次提示: --';
                    
                    // 清除倒计时
                    if (this.countdownInterval) {
                        clearInterval(this.countdownInterval);
                    }
                    
                    // 暂停时释放 Wake Lock
                    this.releaseWakeLock();
                } else {
                    // 恢复时重新请求 Wake Lock
                    this.requestWakeLock();
                    
                    // 恢复时补偿暂停的时间
                    const pauseDuration = Date.now() - this.pauseTime;
                    if (this.lastBeepTime) {
                        this.lastBeepTime += pauseDuration;
                    }
                    this.startTime += pauseDuration;
                    
                    this.pauseBtn.textContent = '⏸️ 暂停';
                    
                    // 根据当前状态恢复显示
                    if (this.countdownFinished) {
                        // 如果已经在锻炼阶段
                        this.countdownEl.textContent = '开始锻炼！';
                        this.countdownEl.style.color = '#27AE60';
                        this.timerLoop(); // 恢复主计时器
                    } else {
                        // 如果还在准备阶段
                        this.countdownEl.textContent = `准备时间: ${this.remainingCountdown}秒`;
                        this.countdownEl.style.color = '#E67E22';
                        this.startCountdown(); // 重新开始倒计时
                    }
                }
            }
            
            resetTimer() {
                this.isRunning = false;
                this.paused = false;
                this.currentCount = 0;
                this.completionTime = null;
                this.countdownFinished = false;
                this.remainingCountdown = 10;
                
                // 清除所有计时器
                if (this.countdownInterval) {
                    clearInterval(this.countdownInterval);
                    this.countdownInterval = null;
                }
                
                // 释放 Wake Lock
                this.releaseWakeLock();
                
                this.totalCount = parseInt(this.totalCountInput.value) || 10;
                
                this.updateDisplay();
                
                this.startBtn.disabled = false;
                this.pauseBtn.disabled = true;
                this.pauseBtn.textContent = '⏸️ 暂停';
                
                this.totalTimeEl.textContent = '总时间: 00:00:00';
                this.nextBeepEl.textContent = '下一次提示: --';
                this.countdownEl.textContent = '准备时间: --';
                this.countdownEl.style.color = '#E67E22';
            }
            
            async completeTimer() {
                this.isRunning = false;
                this.paused = false;
                this.completionTime = Date.now();
                
                // 完成时释放 Wake Lock
                this.releaseWakeLock();
                
                this.startBtn.disabled = false;
                this.pauseBtn.disabled = true;
                
                this.countdownEl.textContent = '锻炼完成！';
                this.countdownEl.style.color = '#E74C3C';
                this.nextBeepEl.textContent = '下一次提示: --';
                
                this.updateDisplay();
                
                // 等待完成音播放完毕后再显示弹窗
                await this.playCompletionSound();
                
                const elapsed = (this.completionTime - this.startTime) / 1000;
                const hours = Math.floor(elapsed / 3600);
                const minutes = Math.floor((elapsed % 3600) / 60);
                const seconds = Math.floor(elapsed % 60);
                
                alert(`恭喜！已完成 ${this.totalCount} 次锻炼，总用时: ${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`);
            }
        }

        document.addEventListener('DOMContentLoaded', () => {
            new RehabTimer();
        });
    </script>
</body>
</html>